const fs = require('fs');
const path = require('path');
const { spawn } = require('child_process');

class VideoMerger {
  constructor() {
    this.downloadsDir = path.join(__dirname, '..', 'downloads');
  }

  // 检查FFmpeg是否可用
  async checkFFmpegAvailable() {
    return new Promise((resolve) => {
      const ffmpeg = spawn('ffmpeg', ['-version']);
      
      ffmpeg.on('error', () => {
        resolve(false);
      });
      
      ffmpeg.on('close', (code) => {
        resolve(code === 0);
      });
    });
  }

  // 扫描下载目录，查找分离的视频和音频文件
  async findSeparatedFiles() {
    const separatedFiles = [];
    
    try {
      const dateDirectories = fs.readdirSync(this.downloadsDir)
        .filter(item => fs.statSync(path.join(this.downloadsDir, item)).isDirectory());

      for (const dateDir of dateDirectories) {
        const datePath = path.join(this.downloadsDir, dateDir);
        const videoDirectories = fs.readdirSync(datePath)
          .filter(item => fs.statSync(path.join(datePath, item)).isDirectory());

        for (const videoDir of videoDirectories) {
          const videoPath = path.join(datePath, videoDir);
          const files = fs.readdirSync(videoPath);
          
          const videoFiles = files.filter(file => 
            /\.(mp4|webm|mkv|avi)$/i.test(file) && !file.includes('audio')
          );
          const audioFiles = files.filter(file => 
            /\.(m4a|mp3|aac|webm)$/i.test(file) && (file.includes('audio') || /\.(m4a|mp3|aac)$/i.test(file))
          );

          // 如果同时存在视频和音频文件，说明可能是分离的
          if (videoFiles.length > 0 && audioFiles.length > 0) {
            separatedFiles.push({
              directory: videoPath,
              videoFiles,
              audioFiles,
              title: videoDir
            });
          }
        }
      }
    } catch (error) {
      console.error('扫描文件时出错:', error.message);
    }

    return separatedFiles;
  }

  // 合并单个视频和音频文件
  async mergeFiles(videoFile, audioFile, outputFile) {
    return new Promise((resolve, reject) => {
      const args = [
        '-i', videoFile,
        '-i', audioFile,
        '-c:v', 'copy',
        '-c:a', 'aac',
        '-strict', 'experimental',
        '-y', // 覆盖输出文件
        outputFile
      ];

      console.log(`开始合并: ${path.basename(videoFile)} + ${path.basename(audioFile)}`);
      
      const ffmpeg = spawn('ffmpeg', args);
      let stderr = '';

      ffmpeg.stderr.on('data', (data) => {
        stderr += data.toString();
        // 解析进度信息
        const timeMatch = stderr.match(/time=(\d{2}:\d{2}:\d{2}\.\d{2})/);
        if (timeMatch) {
          console.log(`合并进度: ${timeMatch[1]}`);
        }
      });

      ffmpeg.on('close', (code) => {
        if (code === 0) {
          console.log(`合并完成: ${path.basename(outputFile)}`);
          resolve(outputFile);
        } else {
          reject(new Error(`FFmpeg 退出代码: ${code}\n${stderr}`));
        }
      });

      ffmpeg.on('error', (err) => {
        reject(new Error(`FFmpeg 执行失败: ${err.message}`));
      });
    });
  }

  // 自动合并所有分离的文件
  async mergeAllSeparatedFiles() {
    const ffmpegAvailable = await this.checkFFmpegAvailable();
    
    if (!ffmpegAvailable) {
      throw new Error('FFmpeg 不可用。请先安装 FFmpeg。参考 FFMPEG_INSTALL_GUIDE.md');
    }

    const separatedFiles = await this.findSeparatedFiles();
    
    if (separatedFiles.length === 0) {
      console.log('没有找到需要合并的分离文件。');
      return [];
    }

    console.log(`找到 ${separatedFiles.length} 个需要合并的视频目录。`);
    
    const mergedFiles = [];

    for (const item of separatedFiles) {
      try {
        // 选择最佳的视频和音频文件进行合并
        const videoFile = path.join(item.directory, item.videoFiles[0]);
        const audioFile = path.join(item.directory, item.audioFiles[0]);
        
        // 生成输出文件名
        const outputFileName = `${item.title}_merged.mp4`;
        const outputFile = path.join(item.directory, outputFileName);
        
        // 如果合并文件已存在，跳过
        if (fs.existsSync(outputFile)) {
          console.log(`跳过已存在的合并文件: ${outputFileName}`);
          continue;
        }

        await this.mergeFiles(videoFile, audioFile, outputFile);
        
        mergedFiles.push({
          directory: item.directory,
          outputFile,
          originalVideo: videoFile,
          originalAudio: audioFile
        });

        // 可选：删除原始分离文件（谨慎操作）
        // fs.unlinkSync(videoFile);
        // fs.unlinkSync(audioFile);
        
      } catch (error) {
        console.error(`合并失败 ${item.title}:`, error.message);
      }
    }

    return mergedFiles;
  }

  // 合并指定目录中的文件
  async mergeDirectory(directoryPath) {
    const ffmpegAvailable = await this.checkFFmpegAvailable();
    
    if (!ffmpegAvailable) {
      throw new Error('FFmpeg 不可用。请先安装 FFmpeg。');
    }

    if (!fs.existsSync(directoryPath)) {
      throw new Error(`目录不存在: ${directoryPath}`);
    }

    const files = fs.readdirSync(directoryPath);
    const videoFiles = files.filter(file => 
      /\.(mp4|webm|mkv|avi)$/i.test(file) && !file.includes('audio')
    );
    const audioFiles = files.filter(file => 
      /\.(m4a|mp3|aac|webm)$/i.test(file) && (file.includes('audio') || /\.(m4a|mp3|aac)$/i.test(file))
    );

    if (videoFiles.length === 0 || audioFiles.length === 0) {
      throw new Error('目录中没有找到可合并的视频和音频文件');
    }

    const videoFile = path.join(directoryPath, videoFiles[0]);
    const audioFile = path.join(directoryPath, audioFiles[0]);
    const outputFile = path.join(directoryPath, 'merged_video.mp4');

    return await this.mergeFiles(videoFile, audioFile, outputFile);
  }
}

// 命令行使用示例
if (require.main === module) {
  const merger = new VideoMerger();
  
  const command = process.argv[2];
  
  if (command === 'scan') {
    // 扫描分离文件
    merger.findSeparatedFiles().then(files => {
      console.log('找到的分离文件:');
      files.forEach((item, index) => {
        console.log(`${index + 1}. ${item.title}`);
        console.log(`   视频: ${item.videoFiles.join(', ')}`);
        console.log(`   音频: ${item.audioFiles.join(', ')}`);
        console.log(`   路径: ${item.directory}`);
        console.log('');
      });
    });
  } else if (command === 'merge-all') {
    // 合并所有分离文件
    merger.mergeAllSeparatedFiles().then(results => {
      console.log(`\n合并完成！共处理 ${results.length} 个文件。`);
      results.forEach(result => {
        console.log(`✓ ${path.basename(result.outputFile)}`);
      });
    }).catch(error => {
      console.error('合并失败:', error.message);
    });
  } else if (command === 'merge-dir' && process.argv[3]) {
    // 合并指定目录
    const targetDir = process.argv[3];
    merger.mergeDirectory(targetDir).then(outputFile => {
      console.log(`合并完成: ${outputFile}`);
    }).catch(error => {
      console.error('合并失败:', error.message);
    });
  } else {
    console.log('视频合并工具使用说明:');
    console.log('');
    console.log('扫描分离文件:');
    console.log('  node src/video-merger.js scan');
    console.log('');
    console.log('合并所有分离文件:');
    console.log('  node src/video-merger.js merge-all');
    console.log('');
    console.log('合并指定目录:');
    console.log('  node src/video-merger.js merge-dir "路径/到/视频目录"');
    console.log('');
    console.log('示例:');
    console.log('  node src/video-merger.js merge-dir "downloads/2025-07-23/视频标题"');
  }
}

module.exports = VideoMerger;